package com.jadobo.xswing.render.impl;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.apache.log4j.Logger;

import com.jadobo.xswing.attrib.IStyle;
import com.jadobo.xswing.model.Form;
import com.jadobo.xswing.model.IElement;
import com.jadobo.xswing.model.ITextElement;
import com.jadobo.xswing.model.Input;
import com.jadobo.xswing.model.Page;
import com.jadobo.xswing.render.IRenderer;
import com.jadobo.xswing.swing.action.SubmitActionListener;
import com.jadobo.xswing.swing.style.IStyleProcessor;
import com.jadobo.xswing.util.Conv;
import com.jadobo.xswing.util.Doc;
import com.jadobo.xswing.util.Str;

public class SwingRenderer implements IRenderer {
	
	private static final Logger LOG = Logger.getLogger(SwingRenderer.class);

	
	private JFrame frame = new JFrame();
	private IStyleProcessor defaultStyleProcessor;
	private SubmitActionListener submitActionListener;
	
	@Override
	public void render(Page startPage) {
		
		// apply default styles.
		defaultStyleProcessor.processPage(startPage);
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setTitle(startPage.getTitle());
		
		Container tgtContainer = setLayout(frame);
		
		renderElement(tgtContainer, startPage.getBody());
		
		tgtContainer.invalidate();
		
		frame.setSize(600, 400);
		frame.setVisible(true);
		
	}

	private Container setLayout(JFrame frame) {
	
		BoxLayout layout = new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS);
		frame.setLayout(layout);
		
		return frame;
		
	}

	private void renderElement(Container container, IElement parentElement) {
		
		if(parentElement == null) {
			LOG.error("Element is NULL");
			return;
		}
		
		for(IElement element : parentElement.getElements()) {
			
			if(element instanceof ITextElement) {
				ITextElement text = (ITextElement) element;
				JLabel jtext = new JLabel(text.getValue());
				IStyle style = text.getStyle(); 
				if(style != null) {
					Font jfont = Conv.font(style.getFont());
					if(jfont != null) { 
						jtext.setFont(jfont);
					}
					
				}
				
				container.add(jtext);
			} else if(element instanceof Form) {
				
				JPanel panel = new JPanel();
				
				// set layout
				BoxLayout layout = new BoxLayout(panel, BoxLayout.Y_AXIS);
				panel.setLayout(layout);
				
				// recursive call
				renderElement(panel, element);
								
				container.add(panel);
				
			} else if(element instanceof Input) {
				
				Input input = (Input) element;
				
				switch(input.getInputType()) {
				case text:
					
					JTextField jtext = new JTextField();
					jtext.setName(input.getName());
					jtext.setText(input.getValue());
					
					Dimension maximumSize = new Dimension(250, 25);
					jtext.setMaximumSize(maximumSize );
					
					container.add(jtext);
					
					break;
				case submit:
					
					JButton jbutton = new JButton();
					jbutton.setText(input.getValue());
					
					String pageName = Doc.getParentFormAction(element);
					submitActionListener.setPageName(pageName );
					submitActionListener.setTarget(frame);
					submitActionListener.setRenderer(this);
					
					jbutton.addActionListener(submitActionListener);
					
					container.add(jbutton);
					
					
					break;
				default:
					LOG.warn(Str.format("Unhandled INPUT type [%s]", input.getInputType()));
				}
			}
			
		}
		
	}

	/**
	 * @param defaultStyleProcessor the defaultStyleProcessor to set
	 */
	public void setDefaultStyleProcessor(IStyleProcessor defaultStyleProcessor) {
		this.defaultStyleProcessor = defaultStyleProcessor;
	}

	/**
	 * @param submitActionListener the submitActionListener to set
	 */
	public void setSubmitActionListener(SubmitActionListener submitActionListener) {
		this.submitActionListener = submitActionListener;
	}

}
